# -*- coding: utf-8 -*-
import json
import time
import hashlib
import logging
import requests
from django.conf import settings

from common.cache import redis_cache
from common.transaction.model import *
from common.utils.exceptions import ParamError, ServerError
from common.withdraw import check_daily_risk
from common.withdraw.db import withdraw_success_action, withdraw_failed_action

_LOGGER = logging.getLogger('alipay')

_APPID_ = 'JUST'


def generate_sign(parameter, key):
    s = ''
    for k in sorted(parameter.keys()):
        s += '%s=%s&' % (k, parameter[k])
    s += 'key=%s' % key
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().upper()
    return sign


def create_order(order_id, payee_no, payee_name, amount, user_id):
    parameter_dict = {
        'mch_id': settings.JUSTPAY_MCH_ID,
        'out_trade_no': order_id,
        'user_id': user_id,
        'total_fee': amount,
        'payee_no': payee_no,
        'payee_real_name': payee_name,
        'notify_url': "%s%s" % (settings.EXCHANGE_CALLBACK_URL, _APPID_),
    }
    parameter_dict['sign'] = generate_sign(parameter_dict, settings.JUSTPAY_API_KEY)
    res = requests.post(settings.JUSTPAY_TRANS_URL, data=parameter_dict, timeout=5).text
    _LOGGER.info("justpay data after charge: %s", res)
    res_dict = json.loads(res)
    if res_dict['status'] != 0:
        raise ServerError('pay service response %s %s' % (res_dict['status'], res_dict['msg']))
    return res_dict.get('data')


def _verify_notify_sign(data):
    sign = data['sign']
    data.pop('sign')
    calculated_sign = generate_sign(data, settings.JUSTPAY_API_KEY)
    if sign != calculated_sign:
        _LOGGER.info("just_withdraw sign: %s, calculated sign: %s", sign, calculated_sign)
        raise ParamError('sign not pass, data: %s' % data)


def check_just_withdraw_notify(request):
    data = request.POST.dict()
    _verify_notify_sign(data)
    order_id = data['out_trade_no']
    trade_status = int(data['order_result'])
    if not order_id:
        _LOGGER.error("just_withdraw fatal error, data: %s" % data)
        raise ParamError('just_withdraw event does not contain valid order ID')

    if trade_status == 2:
        amount = data['total_fee']
        trade_no = data['trade_no']
        succ = withdraw_success_action(order_id, amount, trade_no, payer_no='justpay')
        if succ:
            _LOGGER.info('Auto trans alipay, check_just_withdraw_notify_sign succ')
            check_daily_risk(float(amount))
    elif trade_status == 1:
        extend = json.loads(data['extend'])["auto_trans_info"]
        withdraw_failed_action(order_id, data['total_fee'], extend['code'],
            extend['sub_code'], extend['sub_msg'], extend['out_biz_no'], payer_no='justpay')


def query_withdraw_channels():
    parameter_dict = {
        'mch_id': settings.JUSTPAY_MCH_ID,
    }
    parameter_dict['sign'] = generate_sign(parameter_dict, settings.JUSTPAY_API_KEY)
    res = requests.post(settings.JUSTPAY_TRANS_QUERY_CHANNELS, data=parameter_dict, timeout=5).text
    _LOGGER.info("justpay query_withdraw_channels: %s", res)
    res_dict = json.loads(res)
    if res_dict['status'] != 0:
        raise ServerError('pay service response %s %s' % (res_dict['status'], res_dict['msg']))
    return res_dict.get('data')
